<?php
/* 
	This file is Copyright Matthew Wilkinson 2009.
	
	This file is part of Oxygen.

	Oxygen is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License version 3 as published by
	the Free Software Foundation at http://www.gnu.org/licenses/gpl-3.0.html

	Oxygen is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

*/
	
	Final Class Settings
		{
		
		
		private static $settings = Array();
		private static $constraints = Array();
		
		private static $jsoncache = Array();
		
		private static $constructed = FALSE;
		private static function _construct()
			{
			if (self::$constructed)
				{
				return;
				}
			else
				{
				self::$constructed = TRUE;
				}
			$dbsettings = Database::query('SELECT * FROM settings');
			foreach ($dbsettings as $setting)
				{
				$this->constraints[$setting['component']][$setting['setting']] = $setting['constraint'];
				if (stripos($setting['constraint'], 'int') === 0 OR stripos($setting['constraint'], 'date') === 0)
					{
					settype($settings['value'], 'int');
					}
				elseif (stripos($setting['constraint'], 'string') === 0)
					{
					settype($settings['value'], 'string');
					}
				elseif (stripos($setting['constraint'], 'boolean') === 0)
					{
					settype($setting['value'], 'boolean');
					}
				elseif (stripos($setting['constraint'], 'array') === 0)
					{
					$setting['value'] = json_decode($setting['value']);
					}
				$this->settings[$setting['component']][$setting['setting']] = $setting['value'];
				}
			}
		
		public static function get($setting)
			{
			self::_construct();
			$caller = Security::Caller();
			if (isset(self::$settings[$caller][$setting]))
				{
				return self::$settings[$caller][$setting];
				}
			else
				{
				throw new RuntimeException('settings/invalid_setting');
				}
			}

		
		public static function set($setting, $value)
			{
			self::_construct();
			$comp = Security::Caller();
			$cons = $this->constraints[$comp][$setting];
			$match = Array();
			if (preg_match('/\((.*?)\)/', $cons, $match) == 1)
				{
				$param = $match[1];
				}
			else
				{
				$param = null;
				}
			$commit = FALSE;
			if ($cons == '')
				{
				$commit = TRUE;
				}
			elseif ((stripos($cons, 'int') === 0 AND is_int($value)) AND (($param !== null AND $value <= $param) OR $param === null))
				{
				$commit = TRUE;
				}
			elseif ((stripos($cons, 'string') === 0 AND is_string($value)) AND (($param !== null AND strlen($value) <= $param) OR $param === null))
				{
				$commit = TRUE;
				}
			elseif ((stripos($cons, 'date') === 0 AND is_int($value)) AND (($param !== null AND $value <= $param) OR $param === null))
				{
				$commit = TRUE;
				}
			elseif (stripos($cons, 'boolean') === 0 AND is_bool($value))
				{
				$commit = TRUE;
				}
			elseif ((stripos($cons, 'array') === 0 AND is_array($value)) AND (($param !== null AND count($value) <= $param) OR $param === null))
				{
				$value = json_encode($value);
				$commit = TRUE;
				}
			
			if ($commit)
				{
				Database::query('UPDATE settings SET value="' . $value . '" WHERE component="' . $comp . '" AND setting="' . $setting . '"');
				}
			else
				{
				throw new InvalidArgumentException('settings/constraint_violation');
				}
			}
		
		public static function describe($component, $setting)
			{
			self::_construct();
			$component = Security::string($component);
			if (!isset(self::$jsoncache[$component]))
				{
				self::$jsoncache[$component] = json_decode(file_get_contents('components/' . $component . '/settings.json'));
				}
			return self::$jsoncache[$component][$setting]['description'];
			}
		
		}

?>